当前位置:  开发笔记 > IOS > 正文

Swift`rethrows`函数作为参数传递导致编译器错误

如何解决《Swift`rethrows`函数作为参数传递导致编译器错误》经验,为你挑选了1个好方法。

在Swift 2中,即使函数中没有任何调用可以抛出,下面的函数也不会编译.

func function1(f: Optional U>, x: Optional) -> Optional {
    return f.flatMap(x.map) // Call can throw, but it is not marked with 'try' and the error is not handled
}

此版本的函数与第一个版本相同(并且更详细),但它编译.

func function2(f: Optional U>, x: Optional) -> Optional {
    return f.flatMap { g in
        x.map(g)
    }
}

mixel.. 6

这些版本不完全相同,我解释原因.

假设你有函数,rethrows因为它接受抛出函数作为参数:

func a(x: () throws -> ()) rethrows {
  try x()
}

所以a(x)只有投掷才会x()抛出.

如果你有b抛出的功能:

func b() throws {
}

然后你必须a(b)用try 调用:

try a(b)
a(b) // gives "Call can throw but is not marked with 'try'"

但如果你传递给a不投掷功能:

func c() {
}

然后斯威夫特编译器足够聪明,以确定x()a函数体实际上不扔,它允许简单地调用a(c):

a(c) // it's ok

这是因为:

throws关键字是函数类型的一部分,nonthrowing函数是抛出函数的子类型.因此,您可以在与抛出函数相同的位置使用非抛出函数.

回到你的例子.

Optional.flatMap() 定义为:

public func flatMap(@noescape f: (Wrapped) throws -> U?) rethrows -> U?

在你的例子中f.flatMap有类型((T -> U) throws -> U?) rethrows -> U?.

你看到它重新抛出,因为它接受抛出函数参数并且必须被调用,try除非f有类型Wrapped -> U?并且不抛出.

Optional.map 定义为:

public func map(@noescape f: (Wrapped) throws -> U) rethrows -> U?

所以x.map有型(T throws -> U) rethrows -> U?.

当你调用f.flatMap { g in x.map(g) }编译器看到它gT -> U类型并且不抛出时x.map(g),{ g in x.map(g) }并且f.flatMap { g in x.map(g) }都是安全的并且不抛出.

但是,当你调用f.flatMap(x.map)所有编译器看到的那个x.map(T throws -> U) rethrows -> U?类型并且可以(重新)抛出因此f.flatMap(x.map)不安全而且可以(重新)抛出并且必须被调用时try.



1> mixel..:

这些版本不完全相同,我解释原因.

假设你有函数,rethrows因为它接受抛出函数作为参数:

func a(x: () throws -> ()) rethrows {
  try x()
}

所以a(x)只有投掷才会x()抛出.

如果你有b抛出的功能:

func b() throws {
}

然后你必须a(b)用try 调用:

try a(b)
a(b) // gives "Call can throw but is not marked with 'try'"

但如果你传递给a不投掷功能:

func c() {
}

然后斯威夫特编译器足够聪明,以确定x()a函数体实际上不扔,它允许简单地调用a(c):

a(c) // it's ok

这是因为:

throws关键字是函数类型的一部分,nonthrowing函数是抛出函数的子类型.因此,您可以在与抛出函数相同的位置使用非抛出函数.

回到你的例子.

Optional.flatMap() 定义为:

public func flatMap(@noescape f: (Wrapped) throws -> U?) rethrows -> U?

在你的例子中f.flatMap有类型((T -> U) throws -> U?) rethrows -> U?.

你看到它重新抛出,因为它接受抛出函数参数并且必须被调用,try除非f有类型Wrapped -> U?并且不抛出.

Optional.map 定义为:

public func map(@noescape f: (Wrapped) throws -> U) rethrows -> U?

所以x.map有型(T throws -> U) rethrows -> U?.

当你调用f.flatMap { g in x.map(g) }编译器看到它gT -> U类型并且不抛出时x.map(g),{ g in x.map(g) }并且f.flatMap { g in x.map(g) }都是安全的并且不抛出.

但是,当你调用f.flatMap(x.map)所有编译器看到的那个x.map(T throws -> U) rethrows -> U?类型并且可以(重新)抛出因此f.flatMap(x.map)不安全而且可以(重新)抛出并且必须被调用时try.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有